package com.touzbi.hss.validator;

import java.util.regex.Pattern;

public class Validator implements AbstractValidator {

	private static final int FIRST_NAME_MIN_LENGTH = 3;
	private static final int LAST_NAME_MIN_LENGTH = 3;
	private static final int MAX_NAME_LENGTH = 15;

	private static final String EXCEPTION_EMPTY_NAME = "Please enter a first name";
	private static final String EXCEPTION_EMPTY_LAST_NAME = "Please enter a last name";
	private static final String EXCEPTION_EMPTY_MAIL = "Please enter an email address";
	private static final String EXCEPTION_EMPTY_PHONE_NUMBER = "Please enter a phone number";

	private static final String EXCEPTION_NAME_TOO_SHORT = "First name too short, please enter a name with more than "
			+ FIRST_NAME_MIN_LENGTH + " letters";
	private static final String EXCEPTION_LAST_NAME_TOO_SHORT = "Last name too short, please enter a name with more than "
			+ LAST_NAME_MIN_LENGTH + " letters";

	private static final String EXCEPTION_MALFORMED_EMAIL_ADDRESS = "Please enter a valid email adress (e.g test@test.com)";
	private static final String EXCEPTION_MALFORMED_PHONE_NUMBER = "Please enter a valid phone number";
	private static final String EXCEPTION_MALFORMED_NAME = "Please enter a valid name";

	private static final String MAIL_ADDRESS_REGEX = "([^.@]+)(\\.[^.@]+)*@([^.@]+\\.)+([^.@]+)";
	private static final String PHONE_NUMBER_REGEX = "[0-9]{10}";
	private static final String NAME_REGEX = "([a-z]|[A-Z]|é|è){0,"
			+ +MAX_NAME_LENGTH + "}";

	private boolean isValidMail(String param) {
		return Pattern.matches(MAIL_ADDRESS_REGEX, param);
	}

	private boolean isValidPhoneNumber(String param) {
		return Pattern.matches(PHONE_NUMBER_REGEX, param);
	}

	private boolean isValidName(String param) {
		return Pattern.matches(NAME_REGEX, param);
	}

	private String firstLetterToUpperCase(String param) {
		return param.length() > 1 ? param.substring(0, 1).toUpperCase()
				+ param.substring(1).toLowerCase() : param;
	}

	@Override
	public String getValidFirstName(String param) throws ValidatorException {
		if (param.isEmpty()) {
			throw new ValidatorException(EXCEPTION_EMPTY_NAME);
		} else if (param.length() < FIRST_NAME_MIN_LENGTH) {
			throw new ValidatorException(EXCEPTION_NAME_TOO_SHORT);
		} else if (!isValidName(param)) {
			throw new ValidatorException(EXCEPTION_MALFORMED_NAME);
		}
		param = firstLetterToUpperCase(param);
		return param;
	}

	@Override
	public String getValidLastName(String param) throws ValidatorException {
		if (param.isEmpty()) {
			throw new ValidatorException(EXCEPTION_EMPTY_LAST_NAME);
		} else if (param.length() < LAST_NAME_MIN_LENGTH) {
			throw new ValidatorException(EXCEPTION_LAST_NAME_TOO_SHORT);
		} else if (!isValidName(param)) {
			throw new ValidatorException(EXCEPTION_MALFORMED_NAME);
		}
		param = firstLetterToUpperCase(param);
		return param;
	}

	@Override
	public String getValidMail(String param) throws ValidatorException {
		if (param.isEmpty()) {
			throw new ValidatorException(EXCEPTION_EMPTY_MAIL);
		} else if (!isValidMail(param)) {
			throw new ValidatorException(EXCEPTION_MALFORMED_EMAIL_ADDRESS);
		}
		return param;
	}

	@Override
	public String getValidPhoneNumber(String param) throws ValidatorException {
		if (param.isEmpty()) {
			throw new ValidatorException(EXCEPTION_EMPTY_PHONE_NUMBER);
		} else if (!isValidPhoneNumber(param)) {
			throw new ValidatorException(EXCEPTION_MALFORMED_PHONE_NUMBER);
		}
		return param;
	}

}
